
#ifndef __BROKER_MESSAGE_H
#define __BROKER_MESSAGE_H

#include <apr_file_io.h>
#include "../iface/debug.h"
#include "../net/EncMessage.h"
#include "../aprtools/APRMutex.h"

#include "../db/ActorsDB.h"
#include "../db/KeyDB.h"
#include "../db/Key.h"
#include "../db/PendingDB.h"
#include "../db/NetworkDB.h"

typedef struct all_databases
{
   ActorsDB *actorsdb;
   KeyDB *keydb;
   PendingDB *pendingdb;
   NetworkDB *networkdb;
} AllDBs;

/** This defines the broker message interface. This is the high-level
 * interface to the broker message which assumes futher structural
 * elements over the encapsulated message.
 * 
 * The general design principle is that there is a first header block
 * which contains the actor sending the message and the actor
 * receiving it. This has a content length after it describing the
 * length of the next part of the message.
 * 
 * This content length refers to the encrypted header chunk of the
 * text.  It is an encrypted set of parameters that describe the
 * content of the message. It also contains a content length header,
 * which describes a final block of data containing the real content
 * of the message.
 * 
 * Unless the process reading the message is the intended recipient
 * and has the correct keys, the data in the message is completely
 * unknown. */
class BrokerMessage : public EncMessage
{
   public:
      /** Constructor for the broker message class. */
      BrokerMessage(apr_pool_t *imp) : EncMessage(imp) {}
      /** Copy constructor for the broker message class. */
      BrokerMessage(const BrokerMessage &other) : EncMessage(other) {}
      void insertKeyToSend(int keyslot_number, const char *keyname,
         const char *ownpwd, Key::keypurposetype tpurpose, KeyDB *kdb);
      AbstractKey *obtainAbstractKeyFromReceived(int keyslot_number, Key::keypurposetype tpurpose, KeyDB *kdb);
      int obtainKeyFromReceived(int keyslot_number, const char *addmarks,
         const char *removemarks, Key::keypurposetype tpurpose, const char *owner,
         bool useownpwd, const char *override_name, KeyDB *kdb);
      void insertAllKeysToSend(int keyslot_number, const char *keyname,
         const char *ownpwd, KeyDB *kdb);
      void insertAvailableKeysToSend(int keyslot_number, const char *keyname,
         const char *ownpwd, KeyDB *kdb);
      void insertSecretKeysToSend(int keyslot_number, const char *keyname,
         const char *ownpwd, KeyDB *kdb);
      void insertSSHKeysToSend(int keyslot_number, const char *keyname,
         const char *ownpwd, KeyDB *kdb);
      int obtainAllKeysFromReceived(int keyslot_number,
         const char *addmarks, const char *removemarks, const char *owner,
         bool useownpwd, const char *override_name, KeyDB *kdb);
      int obtainAvailableKeysFromReceived(int keyslot_number,
         const char *addmarks, const char *removemarks, const char *owner,
         bool useownpwd, const char *override_name, KeyDB *kdb);
      int obtainSecretKeysFromReceived(int keyslot_number,
         const char *addmarks, const char *removemarks, const char *owner,
         bool useownpwd, const char *override_name, KeyDB *kdb);
      int obtainSSHKeysFromReceived(int keyslot_number,
         const char *addmarks, const char *removemarks, const char *owner,
         bool useownpwd, const char *override_name, KeyDB *kdb);
      int writePayloadOutToExistingFile(int payload_number, const char *iformatfname, ...) PRINTF_LIKE(3, 4);
      int writePayloadOutToOverwriteFile(int payload_number, const char *iformatfname, ...) PRINTF_LIKE(3, 4);
      int writePayloadOutToReplaceFile(int payload_number, const char *iformatfname, ...) PRINTF_LIKE(3, 4);
      apr_size_t attachHashAndThenFile(const char *iformatfname, ...) PRINTF_LIKE(2, 3);
      int sendEncryptedOnBucketBrigade(APRBucketBrigade *bb, KeyDB *kdb);
      int receiveEncryptedOnBucketBrigade(APRBucketBrigade *bb, KeyDB *kdb, APRMutex *waitinglock);
};

#endif
